﻿using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using SMU_4x1;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
using Color = System.Drawing.Color;

namespace DigitalPowerSupply_V1._3
{
    public partial class FormDPS : Form
    {
        CDriverPowerCard SMU;
        CTimer mTimer;
        ushort CardIndex = 0;//Maybe选择输出通道
        bool exit_flag = false;
        bool CurrentVorI_flag = false;
        ushort I_range = 4;//默认电流档10μA挡
        ushort V_range = 0;//默认20V挡
        double Ix_max = 0.0;
        ushort SelectMode = 3;//恒压恒流模式参数
        ushort Relay_flag= 0;//正向反向模式参数
        bool Bprecharge = false; // 预充电使能默认false，可开放
        int precharge_time = 1000; //预充电时间默认1000us，可开放
        bool bADC_avarage = false;//平均采集默认false，可开放
        ushort I_val = 0;//输出电流参数
        ushort V_val = 0;//输出电压参数

        private Thread ShowResultLoopThread;
        private Thread ReceiveIN_STARTsigLoopThread;
        private Thread ContinuetestLoopThread;
        public FormDPS()
        {
            InitializeComponent();
            cbx_Irange.SelectedIndex = 4;//默认10μA挡
            cbx_Vrange.SelectedIndex = 0;//默认20V挡
            cbx_testIrange.SelectedIndex = 4;//默认10μA挡
            cbx_testVrange.SelectedIndex = 0;//默认20V挡

            cbx_testIrange.SelectedIndex = 4;//默认10μA挡
            cbx_testVrange.SelectedIndex = 0;//默认20V挡

            cbx_ChangeBin0.SelectedIndex = 1;
            cbx_ChangeBin1.SelectedIndex = 1;
            cbx_ChangeBin2.SelectedIndex = 1;
            cbx_ChangeBin3.SelectedIndex = 1;
            cbx_ChangeBin4.SelectedIndex = 1;
            cbx_ChangeBin5.SelectedIndex = 1;
            cbx_ChangeBin6.SelectedIndex = 1;
            cbx_ChangeBin7.SelectedIndex = 1;
            cbx_ChangeBin8.SelectedIndex = 1;
            cbx_ChangeBin9.SelectedIndex = 1;

            mTimer = new CTimer();
            mTimer.Init();//这两行代码创建了一个叫做 mTimer 的 CTimer 对象，并调用了该对象的 Init()方法进行初始化。看起来 mTimer 是一个自定义的计时器类的实例
        }      
        private void btn_ConnectDevice_Click(object sender, EventArgs e)
        {
            ushort pmode = 1;//Maybe源表卡某条指令控制参数
            ushort adc_bypass = 0;//Maybe源表卡某条指令控制参数
            ushort Manual = 1;//手动模式(rB_Manual.Checked)
            if (Manual == 1) { pmode = 1; }
            else { pmode = 3; }
            if (rB_CardIndex1.Checked == true)
                CardIndex = 0;
            else if (rB_CardIndex2.Checked == true)
                CardIndex = 1;
            else if (rB_CardIndex3.Checked == true)
                CardIndex = 2;
            else
                CardIndex = 3;
            SMU = null;
            SMU = new CDriverPowerCard(CardIndex);
            if (SMU.open_flag == 1)
            {
                SMU.WriteIoWord(CardIndex, 0x34, pmode);
                btn_ConnectDevice.BackColor = Color.LimeGreen;
                tlss_connectDevice.Text = "源表卡已连接";
                tlss_connectDevice.ForeColor = Color.Green;
            }
            SMU.ReadIoWord(CardIndex, 0x46, ref adc_bypass);
            label_CurrentVorI.Text= "ADC模式：" + adc_bypass;

            if (ShowResultLoopThread == null || !ShowResultLoopThread.IsAlive)
            {
                ShowResultLoopThread = new Thread(ShowResultLoop);
                ShowResultLoopThread.Start();
            }
        }
        private void ShowResultLoop()//读取、显示电压电流
        {
            double Vx = 0.0;
            double Ix = 0.0;
            string I_Unit = "mA";
            while (exit_flag == false)
            {
                if (CurrentVorI_flag == true)
                {
                    Vx = 0.0;
                    Ix = 0.0;
                    // 读取源表卡里面的五次电压/电流值，取平均
                    for (int i = 0; i < 5; i++)
                    {
                        Vx += SMU.SMU_ReadV(CardIndex, V_range);
                        Ix += SMU.SMU_ReadI(CardIndex, I_range);
                        mTimer.WaitTime(200);
                    }
                    Vx /= 5.0;
                    Ix /= 5.0;
                    if (chbx_calibration.Checked == true)
                    {
                        Vx = SMU.Cali_ResultV((int)V_range, Vx);//电压校准，可换校准函数，也可不校准
                        Ix = SMU.Cali_ResultI((int)I_range, Ix);//电流校准，可换校准函数，也可不校准
                    }                  
                    if (I_range < 3)
                    {
                        I_Unit = "mA";
                        Ix = Ix * 1.0e3;
                    }
                    else
                    {
                        I_Unit = "uA";
                        Ix = Ix * 1.0e6;
                    }
                    if (Ix > Ix_max) { Ix_max = Ix; }
                    label_CurrentVorI.Text = "当前输出电压/电流\n\n电压 = " + Vx.ToString("#0.000") + "V\n\n电流 = " + Ix.ToString("#0.000") + I_Unit + "\n Imax =  " + Ix_max.ToString("#0.000") + I_Unit;
                }
                System.Windows.Forms.Application.DoEvents();
                Thread.Sleep(20);
            }
        }

        private void rB_SelectModeI_Click(object sender, EventArgs e)
        {
            label_Irange.Text = "输出电流档位";
            label_SetLevI.Text = "设定输出电流值";
            label_Vrange.Text = "限电压档位";
            label_SetLevV.Text = "设定限电压值";
            /*label_Irange.Location = new Point(50, 173);
            label_SetLevI.Location = new Point(180, 173);
            label_Vrange.Location = new Point(452, 173);
            label_SetLevV.Location = new Point(578, 173);
            cbx_Irange.Location = new Point(53, 198);
            tbx_SetLevI.Location = new Point(183, 196);
            cbx_Vrange.Location = new Point(455, 198);
            tbx_SetLevV.Location = new Point(581, 196);
            label_UnitI.Location = new Point(321, 201);
            label_UnitV.Location = new Point(719, 201);*/
        }
        private void rB_SelectModeV_Click(object sender, EventArgs e)
        {
            label_Irange.Text = "限电流档位";
            label_SetLevI.Text = "设定限电流值";
            label_Vrange.Text = "输出电压档位";
            label_SetLevV.Text = "设定输出电压值";
            /*label_Irange.Location = new Point(452, 173);
            label_SetLevI.Location = new Point(578, 173);
            label_Vrange.Location = new Point(50, 173);
            label_SetLevV.Location = new Point(180, 173);
            cbx_Irange.Location = new Point(455, 198);
            tbx_SetLevI.Location = new Point(581, 196);
            cbx_Vrange.Location = new Point(53, 198);
            tbx_SetLevV.Location = new Point(183, 196);
            label_UnitI.Location = new Point(719, 201);
            label_UnitV.Location = new Point(321, 201);*/
        }
        private void btn_SaveParameters_Click(object sender, EventArgs e)
        {
            double Icoef = 1.0e-3;
            I_range = (ushort)cbx_Irange.SelectedIndex;//电流档位选择
            V_range = (ushort)cbx_Vrange.SelectedIndex;//电压档位选择
            if(rB_SelectModeI.Checked==true) { SelectMode = 0; }//选择恒流模式
            else if (rB_SelectModeV.Checked == true){ SelectMode = 1;}//选择恒压模式
            else { SelectMode = 3; }//SelectMode = 2？
            if(rB_RelayFW.Checked==true) { Relay_flag = (ushort)EnumRelayCode.FW_Code; }//选择正向输出
            else if (rB_RelayRW.Checked == true) { Relay_flag = (ushort)EnumRelayCode.RV_Code; }//选择反向输出
            else { Relay_flag = 0; }
            if (I_range > 2) { Icoef = 1.0e-6; }//调整不同单位下的电流数值
            else { Icoef = 1.0e-3; }//调整不同单位下的电流数值
            if (SMU == null) { return; }//SMU对象是否存在
            if (SMU.open_flag != 1) { return; }//SMU对象的open_flag属性是否为1
            if (chbx_calibration.Checked == true)
            {
                //应用校正
                double Vset = 0.0;
                double Iset = 0.0;
                Vset = double.Parse(tbx_SetLevV.Text);
                Iset = double.Parse(tbx_SetLevI.Text) * Icoef;

                Vset = SMU.Cali_Vset((int)V_range, Vset);
                Iset = SMU.Cali_Iset((int)I_range, Iset);

                V_val = SMU.VDriverToBin(Vset, (int)V_range);
                I_val = SMU.IDriverToBin(Iset, (int)I_range);
            }
            else
            {
                //不应用校正
                V_val = SMU.VDriverToBin(double.Parse(tbx_SetLevV.Text), (int)V_range);
                I_val = SMU.IDriverToBin(double.Parse(tbx_SetLevI.Text) * Icoef, (int)I_range);
            }
            uint cmdId = 0;//命令地址默认0，可开放
            double Waittime = 0.0;//等待时间默认0.0，可开放         
            SMU.WriteParamVolCurr(CardIndex, cmdId, (PowerCardOutPutMode)SelectMode, V_val, (int)V_range, I_val, (int)I_range, Bprecharge, precharge_time);
            SMU.WriteParamOther(CardIndex, cmdId, (bADC_avarage == true) ? PowerCardMeasMode.Average : PowerCardMeasMode.Real, (EnumRelayCode)Relay_flag, Waittime);
            if (SelectMode == 0)
            {
                if (Relay_flag == (ushort)EnumRelayCode.FW_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   正向输出   输出值：" + double.Parse(tbx_SetLevI.Text) + "μA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   正向输出   输出值：" + double.Parse(tbx_SetLevI.Text) + "mA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                }
                else if (Relay_flag == (ushort)EnumRelayCode.RV_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   反向输出   输出值：" + double.Parse(tbx_SetLevI.Text) + "μA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   反向输出   输出值：" + double.Parse(tbx_SetLevI.Text) + "mA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                }
                else
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   换向继电器关闭   输出值：" + double.Parse(tbx_SetLevI.Text) + "μA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   换向继电器关闭   输出值：" + double.Parse(tbx_SetLevI.Text) + "mA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                }
            }
            else if (SelectMode == 1)
            {
                if (Relay_flag == (ushort)EnumRelayCode.FW_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   正向输出   输出值：" + double.Parse(tbx_SetLevV.Text) + "V   限电流：" + double.Parse(tbx_SetLevI.Text) + "μA";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   正向输出   输出值：" + double.Parse(tbx_SetLevV.Text) + "V   限电流：" + double.Parse(tbx_SetLevI.Text) + "mA";
                    }
                }
                else if (Relay_flag == (ushort)EnumRelayCode.RV_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   反向输出   输出值：" + double.Parse(tbx_SetLevV.Text) + "V   限电流：" + double.Parse(tbx_SetLevI.Text) + "μA";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   反向输出   输出值：" + double.Parse(tbx_SetLevV.Text) + "V   限电流：" + double.Parse(tbx_SetLevI.Text) + "mA";
                    }
                }
                else
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   换向继电器关闭   输出值：" + double.Parse(tbx_SetLevV.Text) + "V   限电流：" + double.Parse(tbx_SetLevI.Text) + "μA";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   换向继电器关闭   输出值：" + double.Parse(tbx_SetLevV.Text) + "V   限电流：" + double.Parse(tbx_SetLevI.Text) + "mA";
                    }
                }
            }
            else
            {
                if (Relay_flag == (ushort)EnumRelayCode.FW_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   正向输出   输出值：" + double.Parse(tbx_SetLevI.Text) + "μA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   正向输出   输出值：" + double.Parse(tbx_SetLevI.Text) + "mA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                }
                else if (Relay_flag == (ushort)EnumRelayCode.RV_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   反向输出   输出值：" + double.Parse(tbx_SetLevI.Text) + "μA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   反向输出   输出值：" + double.Parse(tbx_SetLevI.Text) + "mA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                }
                else
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   换向继电器关闭   输出值：" + double.Parse(tbx_SetLevI.Text) + "μA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   换向继电器关闭   输出值：" + double.Parse(tbx_SetLevI.Text) + "mA   限电压：" + double.Parse(tbx_SetLevV.Text) + "V";
                    }
                }
            }
            if (SMU == null)
                return;
            if (SMU.open_flag != 1)
            {
                CurrentVorI_flag = false;
                return;
            }
            SMU.SMU_0FF(CardIndex);
            CurrentVorI_flag = false;
            Ix_max = 0.0;
            btn_output.BackColor = Color.Gray;
            btn_stopoutput.BackColor = Color.Red;
            label_parametersNow.ForeColor = Color.Black;
            tlss_output.ForeColor = Color.Red;
            tlss_output.Text = "源表卡未输出";
        } 
        private void btn_output_Click(object sender, EventArgs e)
        { 
            if (SMU == null) { return; }//SMU对象是否存在
            if (SMU.open_flag != 1) { return; }//SMU对象的open_flag属性是否为1            
            SMU.WriteIoWord(CardIndex, 0x12, (ushort)(V_val));//输出极限电压20V
            SMU.SMU_ON(CardIndex, I_range, I_val, V_range, V_val, SelectMode, Relay_flag);
            CurrentVorI_flag = true;
            Ix_max = 0.0;
            btn_output.BackColor = Color.Green;
            btn_stopoutput.BackColor = Color.Gray;
            label_parametersNow.ForeColor = Color.Green;
            tlss_output.ForeColor = Color.Green;
            tlss_output.Text = "源表卡正在输出";
        }
        private void btn_stopoutput_Click(object sender, EventArgs e)
        {
            if (SMU == null)
                return;
            if (SMU.open_flag != 1)
            {
                CurrentVorI_flag = false;
                return;
            }
            SMU.SMU_0FF(CardIndex);
            CurrentVorI_flag = false;
            Ix_max = 0.0;
            btn_output.BackColor = Color.Gray;
            btn_stopoutput.BackColor = Color.Red;
            label_parametersNow.ForeColor = Color.Black;
            tlss_output.ForeColor = Color.Red;
            tlss_output.Text = "源表卡未输出";
        }
        private void FormDPS_FormClosing(object sender, FormClosingEventArgs e)
        {
            exit_flag = true;
            if (SMU == null)
                return;
            if (SMU.open_flag == 1)
            {
                SMU.SMU_0FF(CardIndex);
            }
        }
        private void chbx_calibration_CheckedChanged(object sender, EventArgs e)//校准打开/关闭
        {
            if (SMU.open_flag == 1)
            {
                SMU.LoadPowerCardCal(CardIndex);
            }
            if (chbx_calibration.Checked == true)
            {
                tlss_calibration.Text = "正在应用校准数据";
                tlss_calibration.ForeColor = Color.Green;
            }
            else
            {
                tlss_calibration.Text = "未应用校准数据";
                tlss_calibration.ForeColor = Color.Red;
            }
        }
        private void cbx_Irange_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ((ushort)cbx_Irange.SelectedIndex > 2) { label_UnitI.Text = "μA"; }
            else { label_UnitI.Text = "mA"; }
        }
        //以下代码为测试IO寄存器bit0-15读写功能的demo代码，测试完删除
        bool InStart = true;
        bool SendPermission=false;
        bool ReceivePLCsig = false;
        double Vlimit1min = 0.0;
        double Vlimit1max = 0.0;
        double Vlimit2min = 0.0;
        double Vlimit2max = 0.0;
        double Vlimit3min = 0.0;
        double Vlimit3max = 0.0;

        bool BitValueTemp = true;
        bool Bit0Value = true;
        bool Bit1Value = true;
        bool Bit2Value = true;
        bool Bit3Value = true;
        bool Bit4Value = true;
        bool Bit5Value = true;
        bool Bit6Value = true;
        bool Bit7Value = true;
        bool Bit8Value = true;
        bool Bit9Value = true;
        bool Bit12Value = true;
        bool Bit13Value = true;
        bool Bit14Value = true;
        bool Bit15Value = true;
        List<bool> newBitValue = new List<bool> { true, true, true, true, true, true, true, true, true, true };
        private void cbx_ChangeBin0_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(cbx_ChangeBin0.SelectedIndex == 1) { Bit0Value = true; }else if(cbx_ChangeBin0.SelectedIndex == 0) { Bit0Value = false; }
        }
        private void cbx_ChangeBin1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin1.SelectedIndex == 1) { Bit1Value = true; } else if (cbx_ChangeBin1.SelectedIndex == 0) { Bit1Value = false; }
        }
        private void cbx_ChangeBin2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin2.SelectedIndex == 1) { Bit2Value = true; } else if (cbx_ChangeBin2.SelectedIndex == 0) { Bit2Value = false; }
        }
        private void cbx_ChangeBin3_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin3.SelectedIndex == 1) { Bit3Value = true; } else if (cbx_ChangeBin3.SelectedIndex == 0) { Bit3Value = false; }
        }
        private void cbx_ChangeBin4_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin4.SelectedIndex == 1) { Bit4Value = true; } else if (cbx_ChangeBin4.SelectedIndex == 0) { Bit4Value = false; }
        }
        private void cbx_ChangeBin5_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin5.SelectedIndex == 1) { Bit5Value = true; } else if (cbx_ChangeBin5.SelectedIndex == 0) { Bit5Value = false; }
        }
        private void cbx_ChangeBin6_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin6.SelectedIndex == 1) { Bit6Value = true; } else if (cbx_ChangeBin6.SelectedIndex == 0) { Bit6Value = false; }
        }
        private void cbx_ChangeBin7_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin7.SelectedIndex == 1) { Bit7Value = true; } else if (cbx_ChangeBin7.SelectedIndex == 0) { Bit7Value = false; }
        }
        private void cbx_ChangeBin8_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin8.SelectedIndex == 1) { Bit8Value = true; } else if (cbx_ChangeBin8.SelectedIndex == 0) { Bit8Value = false; }
        }
        private void cbx_ChangeBin9_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbx_ChangeBin9.SelectedIndex == 1) { Bit9Value = true; } else if (cbx_ChangeBin9.SelectedIndex == 0) { Bit9Value = false; }
        }
        private void btn_ReceivePLCsig_Click(object sender, EventArgs e)
        {
            if (btn_ReceivePLCsig.Text == "接收信号(IN_START)")
            {
                btn_ReceivePLCsig.Text = "断开信号(IN_START)";
                tlss_PLCSig.ForeColor = Color.Green;
                tlss_PLCSig.Text = "正在接收IN_START信号...";
                btn_ReceivePLCsig.BackColor = Color.Green;
                ReceivePLCsig = true;


                if (ReceiveIN_STARTsigLoopThread == null || !ReceiveIN_STARTsigLoopThread.IsAlive)
                {
                    ReceiveIN_STARTsigLoopThread = new Thread(ReceiveIN_STARTsigLoop);
                    ReceiveIN_STARTsigLoopThread.Start();
                }
                //for (int i = 0; i < 10; i++) { SMU.WriteDIOBit(CardIndex, i, true); }

                /*SMU.SMU_ON(CardIndex, 3, 5, 0, 20, 0, 0x4009);//输出5mA,限电压20V的正向恒流
                //设置2个电压档测试一下
                int Bit = 0;
                bool BitValue = true;                
                double VtestResult = 0.0;
                //读取测试的电压值
                double Vx = 0.0;
                double Ix = 0.0;
                string I_Unit = "mA";
                if (CurrentVorI_flag == true)
                {
                    Vx = 0.0;
                    Ix = 0.0;
                    // 读取源表卡里面的五次电压/电流值，取平均
                    for (int i = 0; i < 5; i++)
                    {
                        Vx += SMU.SMU_ReadV(CardIndex, V_range);
                        Ix += SMU.SMU_ReadI(CardIndex, I_range);
                        mTimer.WaitTime(200);
                    }
                    Vx /= 5.0;
                    Ix /= 5.0;
                    if (chbx_calibration.Checked == true)
                    {
                        Vx = SMU.Cali_ResultV((int)V_range, Vx);//电压校准，可换校准函数，也可不校准
                        Ix = SMU.Cali_ResultI((int)I_range, Ix);//电流校准，可换校准函数，也可不校准
                    }
                    if (I_range < 3)
                    {
                        I_Unit = "mA";
                        Ix = Ix * 1.0e3;
                    }
                    else
                    {
                        I_Unit = "uA";
                        Ix = Ix * 1.0e6;
                    }
                    if (Ix > Ix_max) { Ix_max = Ix; }
                    VtestResult = Vx;
                    List<bool> newBitValue = new List<bool> { true, true, true, true, true, true, true, true, true, true };
                    if (VtestResult >= Vlimit1min && VtestResult < Vlimit1max) { newBitValue = new List<bool>{false,true, true, true, true, true, true, true, true, true}; }
                    else if(VtestResult >= Vlimit2min && VtestResult < Vlimit2max) { newBitValue = new List<bool> { true, true, true, true, true, true, true, true, true, false }; }
                    for(int i = 0; i < 10; i++){ Bit = i; BitValue = newBitValue[i]; SMU.WriteDIOBit(CardIndex, Bit, BitValue); }
                    SMU.WriteDIOBit(CardIndex, 14, false);
                }*/
            }
            else if(btn_ReceivePLCsig.Text == "断开PLC信号")
            {
                btn_ReceivePLCsig.Text = "接收PLC信号";
                btn_ReceivePLCsig.BackColor = Color.Red;
                tlss_PLCSig.ForeColor = Color.Red;
                tlss_PLCSig.Text = "未接收IN_START信号...";

                InStart = true;
                SendPermission = false;
                ReceivePLCsig = false;    
            }
        }
        private void ReceiveIN_STARTsigLoop()
        {
            while (ReceivePLCsig == true)
            {
                InStart = SMU.ReadDIOBit(CardIndex, 11);//读取bit11：IN_START的值  
                System.Windows.Forms.Application.DoEvents();
                Thread.Sleep(20);
                newBitValue = new List<bool> { Bit0Value, Bit1Value, Bit2Value, Bit3Value, Bit4Value, Bit5Value, Bit6Value, Bit7Value, Bit8Value, Bit9Value };
                for (int i = 0; i < 10; i++) { BitValueTemp = newBitValue[i]; SMU.WriteDIOBit(CardIndex, i, BitValueTemp); }
                if (InStart == true) { SendPermission = false; }
                else if (InStart == false) { SendPermission = true; }

                Thread.Sleep(20);
            }
        }
        private void btn_SendEOT_Click(object sender, EventArgs e)
        {           
            if (SendPermission == true) { SMU.WriteDIOBit(CardIndex, 14, false); }
            else if (SendPermission == false) { SMU.WriteDIOBit(CardIndex, 14, true); }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int BitTemp = 0;
            bool BitTempValue1 = false;
            BitTemp = int.Parse(textBox1.Text);
            BitTempValue1 = SMU.ReadDIOBit(CardIndex, BitTemp);
            MessageBox.Show($"Bit {BitTemp} value is {BitTempValue1}");
        }
        private void button2_Click(object sender, EventArgs e)
        {
            int BitTemp = 0;
            BitTemp = int.Parse(textBox1.Text);
            SMU.WriteDIOBit(CardIndex, BitTemp, false);
        }
        private void button3_Click(object sender, EventArgs e)
        {
            int BitTemp = 0;
            BitTemp = int.Parse(textBox1.Text);
            SMU.WriteDIOBit(CardIndex, BitTemp, true);
        }

        private void FormDPS_Load(object sender, EventArgs e)
        {
            // 设置 DataGridView 的列数
            dataGridView_testResult.ColumnCount = 2;
            // 设置 DataGridView 的行数
            dataGridView_testResult.RowCount = 16;
            dataGridView_testResult.Columns[0].HeaderText = "测试项目1：V";
            dataGridView_testResult.Columns[1].HeaderText = "测试项目2：I";
            for (int i = 0; i < 15; i++)
            {
                dataGridView_testResult.Rows[i].HeaderCell.Value = $"{i+1}";
            }

            label_ExcelSavePath.Text = "保存路径：" + Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        }

        private void btn_testSaveParameters_Click(object sender, EventArgs e)
        {
            double Icoef = 1.0e-3;
            I_range = (ushort)cbx_testIrange.SelectedIndex;//电流档位选择
            V_range = (ushort)cbx_testVrange.SelectedIndex;//电压档位选择
            if (rB_testSelectModeI.Checked == true) { SelectMode = 0; }//选择恒流模式
            else if (rB_testSelectModeV.Checked == true) { SelectMode = 1; }//选择恒压模式
            else { SelectMode = 3; }//SelectMode = 2？上面有用，这里没用
            Relay_flag = (ushort)EnumRelayCode.FW_Code; //这里默认选择正向输出
            if (I_range > 2) { Icoef = 1.0e-6; }//调整不同单位下的电流数值
            else { Icoef = 1.0e-3; }//调整不同单位下的电流数值
            if (SMU == null) { return; }//SMU对象是否存在
            if (SMU.open_flag != 1) { return; }//SMU对象的open_flag属性是否为1
            if (chbx_calibration.Checked == true)
            {
                //应用校正
                double Vset = 0.0;
                double Iset = 0.0;
                Vset = double.Parse(tbx_testSetLevV.Text);
                Iset = double.Parse(tbx_testSetLevI.Text) * Icoef;

                Vset = SMU.Cali_Vset((int)V_range, Vset);
                Iset = SMU.Cali_Iset((int)I_range, Iset);

                V_val = SMU.VDriverToBin(Vset, (int)V_range);
                I_val = SMU.IDriverToBin(Iset, (int)I_range);
            }
            else
            {
                //不应用校正
                V_val = SMU.VDriverToBin(double.Parse(tbx_testSetLevV.Text), (int)V_range);
                I_val = SMU.IDriverToBin(double.Parse(tbx_testSetLevI.Text) * Icoef, (int)I_range);
            }
            uint cmdId = 0;//命令地址默认0，可开放
            double Waittime = 0.0;//等待时间默认0.0，可开放         
            SMU.WriteParamVolCurr(CardIndex, cmdId, (PowerCardOutPutMode)SelectMode, V_val, (int)V_range, I_val, (int)I_range, Bprecharge, precharge_time);
            SMU.WriteParamOther(CardIndex, cmdId, (bADC_avarage == true) ? PowerCardMeasMode.Average : PowerCardMeasMode.Real, (EnumRelayCode)Relay_flag, Waittime);
            if (SelectMode == 0)
            {
                if (Relay_flag == (ushort)EnumRelayCode.FW_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   正向输出   输出值：" + double.Parse(tbx_testSetLevI.Text) + "μA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                        label_testMessage.Text = "当前测试参数\n\n恒流输出：" + double.Parse(tbx_testSetLevI.Text) + "μA\n限电压：" + double.Parse(tbx_testSetLevV.Text) + "V\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   正向输出   输出值：" + double.Parse(tbx_testSetLevI.Text) + "mA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                        label_testMessage.Text = "当前测试参数\n\n恒流输出：" + double.Parse(tbx_testSetLevI.Text) + "mA\n限电压：" + double.Parse(tbx_testSetLevV.Text) + "V\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                }
                else if (Relay_flag == (ushort)EnumRelayCode.RV_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   反向输出   输出值：" + double.Parse(tbx_testSetLevI.Text) + "μA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                        label_testMessage.Text = "当前测试参数\n\n恒流输出：" + double.Parse(tbx_testSetLevI.Text) + "μA\n限电压：" + double.Parse(tbx_testSetLevV.Text) + "V\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   反向输出   输出值：" + double.Parse(tbx_testSetLevI.Text) + "mA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                        label_testMessage.Text = "当前测试参数\n\n恒流输出：" + double.Parse(tbx_testSetLevI.Text) + "mA\n限电压：" + double.Parse(tbx_testSetLevV.Text) + "V\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                }
                else
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   换向继电器关闭   输出值：" + double.Parse(tbx_testSetLevI.Text) + "μA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                        label_testMessage.Text = "当前测试参数\n\n恒流输出：" + double.Parse(tbx_testSetLevI.Text) + "μA\n限电压：" + double.Parse(tbx_testSetLevV.Text) + "V\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒流输出   换向继电器关闭   输出值：" + double.Parse(tbx_testSetLevI.Text) + "mA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                        label_testMessage.Text = "当前测试参数\n\n恒流输出：" + double.Parse(tbx_testSetLevI.Text) + "mA\n限电压：" + double.Parse(tbx_testSetLevV.Text) + "V\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                }
            }
            else if (SelectMode == 1)
            {
                if (Relay_flag == (ushort)EnumRelayCode.FW_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   正向输出   输出值：" + double.Parse(tbx_testSetLevV.Text) + "V   限电流：" + double.Parse(tbx_testSetLevI.Text) + "μA";
                        label_testMessage.Text = "当前测试参数\n\n恒压输出：" + double.Parse(tbx_testSetLevV.Text) + "V\n限电流：" + double.Parse(tbx_testSetLevI.Text) + "μA\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   正向输出   输出值：" + double.Parse(tbx_testSetLevV.Text) + "V   限电流：" + double.Parse(tbx_testSetLevI.Text) + "mA";
                        label_testMessage.Text = "当前测试参数\n\n恒压输出：" + double.Parse(tbx_testSetLevV.Text) + "V\n限电流：" + double.Parse(tbx_testSetLevI.Text) + "mA\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                }
                else if (Relay_flag == (ushort)EnumRelayCode.RV_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   反向输出   输出值：" + double.Parse(tbx_testSetLevV.Text) + "V   限电流：" + double.Parse(tbx_testSetLevI.Text) + "μA";
                        label_testMessage.Text = "当前测试参数\n\n恒压输出：" + double.Parse(tbx_testSetLevV.Text) + "V\n限电流：" + double.Parse(tbx_testSetLevI.Text) + "μA\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   反向输出   输出值：" + double.Parse(tbx_testSetLevV.Text) + "V   限电流：" + double.Parse(tbx_testSetLevI.Text) + "mA";
                        label_testMessage.Text = "当前测试参数\n\n恒压输出：" + double.Parse(tbx_testSetLevV.Text) + "V\n限电流：" + double.Parse(tbx_testSetLevI.Text) + "mA\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                }
                else
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   换向继电器关闭   输出值：" + double.Parse(tbx_testSetLevV.Text) + "V   限电流：" + double.Parse(tbx_testSetLevI.Text) + "μA";
                        label_testMessage.Text = "当前测试参数\n\n恒压输出：" + double.Parse(tbx_testSetLevV.Text) + "V\n限电流：" + double.Parse(tbx_testSetLevI.Text) + "μA\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：恒压输出   换向继电器关闭   输出值：" + double.Parse(tbx_testSetLevV.Text) + "V   限电流：" + double.Parse(tbx_testSetLevI.Text) + "mA";
                        label_testMessage.Text = "当前测试参数\n\n恒压输出：" + double.Parse(tbx_testSetLevV.Text) + "V\n限电流：" + double.Parse(tbx_testSetLevI.Text) + "mA\n连续测试间隔时间：" + double.Parse(tbx_testConiTime.Text) + "ms";
                    }
                }
            }
            else
            {
                if (Relay_flag == (ushort)EnumRelayCode.FW_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   正向输出   输出值：" + double.Parse(tbx_testSetLevI.Text) + "μA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   正向输出   输出值：" + double.Parse(tbx_testSetLevI.Text) + "mA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                    }
                }
                else if (Relay_flag == (ushort)EnumRelayCode.RV_Code)
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   反向输出   输出值：" + double.Parse(tbx_testSetLevI.Text) + "μA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   反向输出   输出值：" + double.Parse(tbx_testSetLevI.Text) + "mA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                    }
                }
                else
                {
                    if (I_range > 2)
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   换向继电器关闭   输出值：" + double.Parse(tbx_testSetLevI.Text) + "μA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                    }
                    else
                    {
                        label_parametersNow.Text = "当前设定输出参数：输出关闭   换向继电器关闭   输出值：" + double.Parse(tbx_testSetLevI.Text) + "mA   限电压：" + double.Parse(tbx_testSetLevV.Text) + "V";
                    }
                }
            }
            if (SMU == null)
                return;
            if (SMU.open_flag != 1)
            {
                CurrentVorI_flag = false;
                return;
            }
            SMU.SMU_0FF(CardIndex);
            CurrentVorI_flag = false;
            Ix_max = 0.0;
            btn_output.BackColor = Color.Gray;
            btn_stopoutput.BackColor = Color.Red;
            label_parametersNow.ForeColor = Color.Black;
            tlss_output.ForeColor = Color.Red;
            tlss_output.Text = "源表卡未输出";
        }

        private void rB_testSelectModeI_Click(object sender, EventArgs e)
        {
            label_testIrange.Text = "电流档位选择:";
            label_testSetLevI.Text = "测试电流值设定:";
            label_testVrange.Text = "限电压档位选择:";
            label_testSetLevV.Text = "测试限电压值设定:";
        }
        private void rB_testSelectModeV_Click(object sender, EventArgs e)
        {
            label_testIrange.Text = "限电流档位选择:";
            label_testSetLevI.Text = "测试限电流值设定:";
            label_testVrange.Text = "电压档位选择:";
            label_testSetLevV.Text = "测试电压值设定:";
        }

        private void btn_testmanual_Click(object sender, EventArgs e)
        {
            // 打开输出
            if (SMU == null) { return; }//SMU对象是否存在
            if (SMU.open_flag != 1) { return; }//SMU对象的open_flag属性是否为1
            SMU.WriteIoWord(CardIndex, 0x12, (ushort)(V_val));//输出极限电压20V
            SMU.SMU_ON(CardIndex, I_range, I_val, V_range, V_val, SelectMode, Relay_flag);
            CurrentVorI_flag = true;
            Ix_max = 0.0;
            btn_output.BackColor = Color.Green;
            btn_stopoutput.BackColor = Color.Gray;
            label_parametersNow.ForeColor = Color.Green;
            tlss_output.ForeColor = Color.Green;
            tlss_output.Text = "源表卡正在输出";

            // 读取并写入测试电压
            Thread.Sleep(20);
            double Vx = 0.0;
            double Ix = 0.0;
            string I_Unit = "mA";
            string testV = null;
            string testI = null;
            if (CurrentVorI_flag == true)
            {
                Vx = 0.0;
                Ix = 0.0;
                // 读取源表卡里面的五次电压/电流值，取平均
                for (int i = 0; i < 5; i++)
                {
                    Vx += SMU.SMU_ReadV(CardIndex, V_range);
                    Ix += SMU.SMU_ReadI(CardIndex, I_range);
                    mTimer.WaitTime(200);
                }
                Vx /= 5.0;
                Ix /= 5.0;
                if (chbx_calibration.Checked == true)
                {
                    Vx = SMU.Cali_ResultV((int)V_range, Vx);//电压校准，可换校准函数，也可不校准
                    Ix = SMU.Cali_ResultI((int)I_range, Ix);//电流校准，可换校准函数，也可不校准
                }
                if (I_range < 3)
                {
                    I_Unit = "mA";
                    Ix = Ix * 1.0e3;
                }
                else
                {
                    I_Unit = "uA";
                    Ix = Ix * 1.0e6;
                }
                if (Ix > Ix_max) { Ix_max = Ix; }
                testV = Vx.ToString("#0.000") + "V";
                testI = Ix.ToString("#0.000") + I_Unit;
            }
            int num_empty = 0;
            for(int i = 0;i < 15; i++)
            {
                if (dataGridView_testResult.Rows[i].Cells[0].Value == null) { num_empty++; }
            }
            if (num_empty >= 1)
            {
                for(int i = 0;i < 15; i++)
                {
                    if(dataGridView_testResult.Rows[i].Cells[0].Value == null) { dataGridView_testResult.Rows[i].Cells[0].Value = testV; dataGridView_testResult.Rows[i].Cells[1].Value = testI; break; }
                }
            }
            else
            {
                int rowIndex = dataGridView_testResult.Rows.Add(); // 向 DataGridView 添加一行，并获取新行的索引
                DataGridViewRow newRow = dataGridView_testResult.Rows[rowIndex]; // 获取新添加的行
                newRow.Cells[0].Value = testV;
                newRow.Cells[1].Value = testI;
                newRow.HeaderCell.Value = $"{dataGridView_testResult.RowCount - 1}";
            }
            // 测试完关闭输出
            if (SMU == null)
                return;
            if (SMU.open_flag != 1)
            {
                CurrentVorI_flag = false;
                return;
            }
            SMU.SMU_0FF(CardIndex);
            CurrentVorI_flag = false;
            Ix_max = 0.0;
            btn_output.BackColor = Color.Gray;
            btn_stopoutput.BackColor = Color.Red;
            label_parametersNow.ForeColor = Color.Black;
            tlss_output.ForeColor = Color.Red;
            tlss_output.Text = "源表卡未输出";
        }
        int continuetest = 0;
        private void btn_testConti_Click(object sender, EventArgs e)
        {
            if (btn_testConti.Text == "连续测试")
            {
                // 打开输出
                if (SMU == null) { return; }//SMU对象是否存在
                if (SMU.open_flag != 1) { return; }//SMU对象的open_flag属性是否为1            
                SMU.WriteIoWord(CardIndex, 0x12, (ushort)(V_val));//输出极限电压20V
                SMU.SMU_ON(CardIndex, I_range, I_val, V_range, V_val, SelectMode, Relay_flag);
                CurrentVorI_flag = true;
                Ix_max = 0.0;
                btn_output.BackColor = Color.Green;
                btn_stopoutput.BackColor = Color.Gray;
                label_parametersNow.ForeColor = Color.Green;
                tlss_output.ForeColor = Color.Green;
                tlss_output.Text = "源表卡正在输出";                

                continuetest = 1;
                if (ContinuetestLoopThread == null || !ContinuetestLoopThread.IsAlive)
                {
                    ContinuetestLoopThread = new Thread(ContinuetestLoop);
                    ContinuetestLoopThread.Start();
                }

                btn_testConti.BackColor = Color.Green;
                btn_testConti.Text = "停止测试";
                tlss_testConti.ForeColor = Color.Green;
                tlss_testConti.Text = "正在测试";
                btn_testSaveParameters.Enabled = false;
                btn_testmanual.Enabled = false;
            }
            else
            {
                // 测试完关闭输出
                continuetest = 0;
                Thread.Sleep(1500);
                if (SMU == null)
                    return;
                if (SMU.open_flag != 1)
                {
                    CurrentVorI_flag = false;
                    return;
                }
                SMU.SMU_0FF(CardIndex);
                CurrentVorI_flag = false;
                Ix_max = 0.0;
                btn_output.BackColor = Color.Gray;
                btn_stopoutput.BackColor = Color.Red;
                label_parametersNow.ForeColor = Color.Black;
                tlss_output.ForeColor = Color.Red;
                tlss_output.Text = "源表卡未输出";               

                btn_testConti.BackColor = Color.Gray;
                btn_testConti.Text = "连续测试";
                tlss_testConti.ForeColor = Color.Red;
                tlss_testConti.Text = "未在测试";
                btn_testSaveParameters.Enabled = true;
                btn_testmanual.Enabled = true;

                string ExcelSavePath = ExcelSaveFoldPath + "\\" + DateTime.Now.ToString("yyyy.MM.dd_HH.mm.ss") + "_test.xlsx";
                using (SpreadsheetDocument document = SpreadsheetDocument.Create(ExcelSavePath, SpreadsheetDocumentType.Workbook))
                {
                    WorkbookPart workbookPart = document.AddWorkbookPart();
                    workbookPart.Workbook = new Workbook();

                    WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                    worksheetPart.Worksheet = new Worksheet(new SheetData());

                    Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());
                    Sheet sheet = new Sheet()
                    {
                        Id = document.WorkbookPart.GetIdOfPart(worksheetPart),
                        SheetId = 1,
                        Name = "Sheet1"
                    };
                    sheets.Append(sheet);

                    // 获取列标题
                    Row headerRow = new Row();
                    foreach (DataGridViewColumn column in dataGridView_testResult.Columns)
                    {
                        headerRow.AppendChild(CreateTextCell(column.HeaderText));
                    }

                    SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
                    sheetData.AppendChild(headerRow);

                    // 添加行数据
                    foreach (DataGridViewRow row in dataGridView_testResult.Rows)
                    {
                        Row newRow = new Row();
                        foreach (DataGridViewCell cell in row.Cells)
                        {
                            newRow.AppendChild(CreateTextCell(cell.Value?.ToString() ?? ""));
                        }
                        sheetData.AppendChild(newRow);
                    }
                }
                MessageBox.Show("文件已保存");
            }
            
        }
        private void ContinuetestLoop()
        {
            // 读取并写入测试电压
            while (continuetest == 1)
            {
                int testConiTime = 1000;
                if (int.TryParse(tbx_testConiTime.Text, out _))
                    testConiTime = int.Parse(tbx_testConiTime.Text);
                Thread.Sleep(testConiTime);
                Thread.Sleep(20);
                double Vx = 0.0;
                double Ix = 0.0;
                string I_Unit = "mA";
                string testV = null;
                string testI = null;
                if (CurrentVorI_flag == true)
                {
                    Vx = 0.0;
                    Ix = 0.0;
                    // 读取源表卡里面的五次电压/电流值，取平均
                    for (int i = 0; i < 5; i++)
                    {
                        Vx += SMU.SMU_ReadV(CardIndex, V_range);
                        Ix += SMU.SMU_ReadI(CardIndex, I_range);
                        mTimer.WaitTime(200);
                    }
                    Vx /= 5.0;
                    Ix /= 5.0;
                    if (chbx_calibration.Checked == true)
                    {
                        Vx = SMU.Cali_ResultV((int)V_range, Vx);//电压校准，可换校准函数，也可不校准
                        Ix = SMU.Cali_ResultI((int)I_range, Ix);//电流校准，可换校准函数，也可不校准
                    }
                    if (I_range < 3)
                    {
                        I_Unit = "mA";
                        Ix = Ix * 1.0e3;
                    }
                    else
                    {
                        I_Unit = "uA";
                        Ix = Ix * 1.0e6;
                    }
                    if (Ix > Ix_max) { Ix_max = Ix; }
                    testV = Vx.ToString("#0.000") + "V";
                    testI = Ix.ToString("#0.000") + I_Unit;
                }
                int num_empty = 0;
                for (int i = 0; i < 15; i++)
                {
                    if (dataGridView_testResult.Rows[i].Cells[0].Value == null) { num_empty++; }
                }
                if (num_empty >= 1)
                {
                    for (int i = 0; i < 15; i++)
                    {
                        if (dataGridView_testResult.Rows[i].Cells[0].Value == null) { dataGridView_testResult.Rows[i].Cells[0].Value = testV; dataGridView_testResult.Rows[i].Cells[1].Value = testI; break; }
                    }
                }
                else
                {
                    int rowIndex = dataGridView_testResult.Rows.Add(); // 向 DataGridView 添加一行，并获取新行的索引
                    DataGridViewRow newRow = dataGridView_testResult.Rows[rowIndex]; // 获取新添加的行
                    newRow.Cells[0].Value = testV;
                    newRow.Cells[1].Value = testI;
                    newRow.HeaderCell.Value = $"{dataGridView_testResult.RowCount - 1}";
                }
            }
        }

        private void btn_testCleanResult_Click(object sender, EventArgs e)
        {
            dataGridView_testResult.Rows.Clear();
            // 设置 DataGridView 的列数
            dataGridView_testResult.ColumnCount = 2;
            // 设置 DataGridView 的行数
            dataGridView_testResult.RowCount = 16;
            dataGridView_testResult.Columns[0].HeaderText = "测试项目1：V";
            dataGridView_testResult.Columns[1].HeaderText = "测试项目2：I";
            for (int i = 0; i < 15; i++)
            {
                dataGridView_testResult.Rows[i].HeaderCell.Value = $"{i + 1}";
            }
        }

        private void btn_exportExcel_Click(object sender, EventArgs e)
        {
            string ExcelSavePath = ExcelSaveFoldPath + "\\" + DateTime.Now.ToString("yyyy.MM.dd_HH.mm.ss") + "_test.xlsx";
            using (SpreadsheetDocument document = SpreadsheetDocument.Create(ExcelSavePath, SpreadsheetDocumentType.Workbook))
            {
                WorkbookPart workbookPart = document.AddWorkbookPart();
                workbookPart.Workbook = new Workbook();

                WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                worksheetPart.Worksheet = new Worksheet(new SheetData());

                Sheets sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());
                Sheet sheet = new Sheet()
                {
                    Id = document.WorkbookPart.GetIdOfPart(worksheetPart),
                    SheetId = 1,
                    Name = "Sheet1"
                };
                sheets.Append(sheet);

                // 获取列标题
                Row headerRow = new Row();
                foreach (DataGridViewColumn column in dataGridView_testResult.Columns)
                {
                    headerRow.AppendChild(CreateTextCell(column.HeaderText));
                }

                SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
                sheetData.AppendChild(headerRow);

                // 添加行数据
                foreach (DataGridViewRow row in dataGridView_testResult.Rows)
                {
                    Row newRow = new Row();
                    foreach (DataGridViewCell cell in row.Cells)
                    {
                        newRow.AppendChild(CreateTextCell(cell.Value?.ToString() ?? ""));
                    }
                    sheetData.AppendChild(newRow);
                }
            }
        }
        private Cell CreateTextCell(string text)
        {
            Cell cell = new Cell(new InlineString(new Text(text)));
            cell.DataType = CellValues.InlineString;
            return cell;
        }

        private void cbx_testIrange_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ((ushort)cbx_testIrange.SelectedIndex > 2) { label__testUnitI.Text = "μA"; }
            else { label__testUnitI.Text = "mA"; }
        }
        string ExcelSaveFoldPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        private void btn_SetExcelSavePath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                ExcelSaveFoldPath = folderBrowserDialog.SelectedPath ;
                label_ExcelSavePath.Text = "保存路径：" + folderBrowserDialog.SelectedPath ;
            }
        }
    }
}
